import { createClient } from 'redis';
import env from './env';

export const genCosTokenKey = (userId: string) =>
  `rin-takeout:cos-token:${userId}`;
export const genCartKey = (userId: string, shopId: number) =>
  `rin-takeout:cart:${userId}:${shopId}`;
export const genMessageKey = ({
  userId,
  shopUserId,
}: { userId: string; shopUserId: string }) =>
  `rin-takeout:message:${userId}:${shopUserId}`;
export const genInChatKey = ({
  userId,
  shopUserId,
}: { userId: string; shopUserId: string }) =>
  `rin-takeout:in-chat:${userId}:${shopUserId}`;
export const genNewMessageButNotInChatKey = ({
  userId,
  shopUserId,
}: { userId: string; shopUserId: string }) =>
  `rin-takeout:new-message-but-not-in-chat:${userId}:${shopUserId}`;
export const genNewMessageNotOnlineKey = (userId: string) =>
  `rin-takeout:new-message-not-online:${userId}`;
export const genNewOrderNotOnlineKey = ({
  userId,
  shopUserId,
}: { userId: string; shopUserId: string }) =>
  `rin-takeout:new-order-not-online:${userId}:${shopUserId}`;

const redis = createClient({
  url: `redis://:${env.REDIS_PASSWORD}@${env.IS_BUILDING ? env.SERVER_IP : env.REDIS_HOST}:${env.REDIS_PORT}`,
});

const connect = () => !redis.isReady && redis.connect();

async function set(key: string, value: string) {
  await connect();
  return redis.set(key, value);
}

async function get(key: string) {
  await connect();
  return redis.get(key);
}

async function del(key: string | string[]) {
  await connect();
  return Array.isArray(key) ? key.map((k) => redis.del(k)) : redis.del(key);
}

async function setEx(key: string, seconds: number, value: string) {
  await connect();
  return redis.setEx(key, seconds, value);
}

async function keys(pattern: string) {
  await connect();
  return redis.keys(pattern);
}

async function hSet(key: string, value: Record<string, any>) {
  await connect();
  return redis.hSet(key, value);
}

async function hGetAll<T>(key: string) {
  await connect();
  return redis.hGetAll(key) as T;
}

async function hGet(key: string, field: string) {
  await connect();
  return redis.hGet(key, field);
}

async function ttl(key: string) {
  await connect();
  return redis.ttl(key);
}

export default {
  set,
  get,
  del,
  setEx,
  keys,
  hSet,
  hGetAll,
  hGet,
  ttl,
};
